package model;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Model zum herunterladen von Dateien aus dem Internet.<br>
 * Bekommt den Speicherpfad der Dateien uebergeben und kann dann mit einer URL Liste beliefert werden.<br><br>
 * Wenn am angegebenen Speicherort eine Datei mit dem gleichen Namen bereits liegt, 
 * wird ein entsprechender Prefix an den Dateinamen gehangen um diesen individuell zu halten.
 */
public class FileLoadModel extends Observable implements Runnable {
    /**
     * Pfad auf dem die Dateien gespeichert werden sollen
     */
    private String path;
    
    /**
     * Liste der zu herunterladenen Dateien
     */
    private ArrayList<String> files;

    /**
     * Initialisiert den Dateipfad mit dem uebergebenen Wert.
     * 
     * @param absolutePath zu nutztender Dateipfad
     */
    public FileLoadModel(String absolutePath) {
        this.path = absolutePath;
    }
    
    /**
     * Nimmt die Liste der zu ladenen URLs entgegen und starten im Anschluss den Download.
     * 
     * @param files zu ladenede URLs
     */
    public void load(ArrayList files) {
        this.files = files;
        Thread thread = new Thread(this);
        thread.start();
    }

    /**
     * Laedt nacheinander die vorher uebergebenen URLs herunter.<br>
     * Der Downloadfortschritt wird dabei regelmaessig an alle Observer geschickt.<br><br>
     *  
     * Bereits vorhandene Dateien werde nicht ueberschrieben, stattdessen wird ein neue Dateiname gewaehlt.
     */
    public void run() {
        for(String url : (ArrayList<String>) this.files) {
            try {
                int ByteRead,ByteWritten=0;
                byte[] buf = new byte[1024];
                
                URL uri = new URL(url);
                URLConnection connection = uri.openConnection();
                connection.setRequestProperty("User-Agent", "Patrick Bauer, s0528597");
                
                int size = connection.getContentLength();
                this.path = this.path.concat("/");
                String fileName = url.substring(url.lastIndexOf("/") + 1);
               
                String fullPath = this.path + fileName;
                String nfileName = fileName;
                
                File f = new File(fullPath);
                int i = 1;
                while(f.exists()) { 
                    nfileName = i + "-".concat(fileName); 
                    f = new File(this.path + nfileName);
                    i++;
                }

                fullPath = this.path + nfileName;
                
                OutputStream os = new BufferedOutputStream(new FileOutputStream(fullPath));
                InputStream is = connection.getInputStream();
                
                while ((ByteRead = is.read(buf)) != -1) {
                    os.write(buf, 0, ByteRead);
                    ByteWritten += ByteRead;
                    
                    this.setChanged();
                    this.notifyObservers(new DownloadProgress(url, (int) (ByteWritten * 100 / size)));
                }
                
                is.close();
                os.close();
            } catch (Exception ex) {
                Logger.getLogger(FileLoadModel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
    }
    
}
